package repositories

import (
	"Squid/common/request"
	"Squid/common/responses"
	db2 "Squid/config/db"
	"Squid/models"
	"Squid/modules/crontab/common"
	"Squid/modules/crontab/master"
	"gorm.io/gorm"
	"math"
)

type JobManager struct {
	db *db2.DB
}

func NewJobManager() (jobManager *JobManager, err error) {
	var (
		db *db2.DB
	)

	if db, err = db2.NewDB(); err != nil {
		return &JobManager{}, err
	}
	return &JobManager{
		db: db,
	}, err
}

func (manager *JobManager) InsertJob(job *models.Job) (id string, err error) {
	var (
		result *gorm.DB
	)

	result = manager.db.Db.Create(job)
	if result.RowsAffected == 1 {
		return job.ID, err
	}
	return "", result.Error
}

func (manager *JobManager) SelectJobById(id string) (job *models.Job, err error) {
	var (
		result *gorm.DB
	)

	result = manager.db.Db.Where("id = ?", id).First(&job)
	if result.RowsAffected == 1 {
		return job, err
	} else {
		return nil, err
	}
}

func (manager *JobManager) UpdateUserById(id string, s *models.Job) (job *models.Job, err error) {
	var (
		result *gorm.DB
	)

	result = manager.db.Db.Model(&models.Job{
		ID: id,
	}).UpdateColumns(s)
	result.Scan(&job)
	return job, result.Error
}

func (manager *JobManager) DeleteJobById(id string) (bool, error) {
	var (
		result *gorm.DB
	)

	result = manager.db.Db.Delete(&models.Job{ID: id})
	if result.RowsAffected >= 1 && result.Error == nil {
		return true, result.Error
	}
	return false, result.Error
}

func (manager *JobManager) SelectJobs(s *request.Job) (results responses.Results, err error) {
	var (
		offset    int
		jobs      *[]models.Job
		job       *models.Job
		count     int64
		totalPage int
	)

	job = new(models.Job)
	job.Name = s.Name
	count = manager.CountJobs(job)
	if count == 0 {
		results.Total = 0
		results.Size = s.Size
		results.Page = s.Page
		results.Lists = make([]interface{}, 0)
		return results, err
	}
	manager.db.Db.Scopes(request.Paginate(offset, s.Size), request.JobSelectOrWhere(s.Name)).Model(&models.Job{}).Order(s.SortFiled + " " + s.Sort).Find(&jobs)
	totalPage = int(math.Ceil(float64(count) / float64(s.Size)))
	return responses.Results{
		Total:     count,
		TotalPage: totalPage,
		Page:      s.Page,
		Size:      s.Size,
		Lists:     jobs,
	}, err

}

func (manager *JobManager) CountJobs(job *models.Job) (count int64) {
	manager.db.Db.Scopes(request.JobSelectOrWhere(job.Name)).Model(&models.Job{}).Count(&count)
	return count
}

func (manager *JobManager) SyncJobToEtcd(id string) (oldJob *common.Job, err error) {
	var (
		result   *gorm.DB
		mysqlJob *models.Job
		etcdJob  common.Job
	)

	result = manager.db.Db.Where("id = ?", id).First(&mysqlJob)
	if result.RowsAffected == 1 && result.Error == nil {
		//将查出来的数据放入到etcd中
		etcdJob = common.Job{
			Name:     mysqlJob.ID,
			Command:  mysqlJob.Command,
			CronExpr: mysqlJob.CronExpr,
		}
		oldJob, err = master.G_jobMgr.SaveJob(&etcdJob)
		return oldJob, err
	} else {
		return oldJob, result.Error
	}
}

func (manager *JobManager) DeleteJobFromEtcd(id string) (oldJob *common.Job, err error) {

	// 去删除任务
	oldJob, err = master.G_jobMgr.DeleteJob(id)
	return oldJob, err
}

func (manager *JobManager) SelectEtcdJobs() (jobList []*common.Job, err error) {

	jobList, err = master.G_jobMgr.ListJobs()
	return jobList, err
}

func (manager *JobManager) KillEtcdJobById(id string) (err error) {

	err = master.G_jobMgr.KillJob(id)
	return err
}

func (manager *JobManager) GetEtcdWorkers() (workerArr []string, err error) {

	workerArr, err = master.G_workerMgr.ListWorkers()
	return workerArr, err
}
